#include "battery.h"

static uint16_t AdcValue[2] = {0};
static float batteryVoltage = 0;
static float batteryPercent = 0;
static float ic_temp = 0; // IC温度

void battery_init(void)
{
    HAL_ADCEx_Calibration_Start(&hadc1);
    // 先停止可能的DMA传输
    // HAL_ADC_Stop_DMA(&hadc1);
    __HAL_DMA_DISABLE_IT(hadc1.DMA_Handle, DMA_IT_HT); // 关闭半传输中断
    // HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 2, 0);    // 比如设成 2
    // HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
    HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&AdcValue, 2); // 启动ADC1，使用DMA，采集两个通道的数据
    // 暂时使用轮询模式测试
    // HAL_ADC_Start(&hadc1);
}

static uint8_t emaInited = 0;
static float emaY = 0.0f;

static float filterVoltage_ema(float x)
{
    const float alpha = 0.1f; // 平滑系数：小=更稳，大=更跟手
    if (!emaInited)
    {
        emaY = x;
        emaInited = 1;
    }
    else
    {
        emaY = emaY + alpha * (x - emaY);
    }
    return emaY;
}

static int lastPercent = -1; // -1 表示未初始化

static int stablePercent(int newPercent)
{
    if (lastPercent < 0)
    {
        lastPercent = newPercent;
        return lastPercent;
    }
    if (newPercent >= lastPercent + 2)
        lastPercent = newPercent;
    else if (newPercent <= lastPercent - 2)
        lastPercent = newPercent;
    return lastPercent;
}

// 检测电压
static float CalculateBatteryVoltage(uint32_t adcValue)
{
    float V_ref = 3.3;    // ADC 参迃电县
    uint32_t R_1 = 10000; // 10KΩ 电阻
    uint32_t R_2 = 10000; // 3.3KΩ 电阻

    float V_adc = (float)adcValue * V_ref / 4095.0;         // 计算 ADC 引脚电压
    float V_in = V_adc * ((float)(R_1 + R_2) / (float)R_2); // 计算电池电压

    if (V_in >= 4.15)
        V_in += 0.40; // 大于4.25说明是USB供电，需要补偿电路设计上二极管压降的450mV

    return V_in; // 考虑校准误差
}

// 检测电压并转换为0-100的浮点数
static float ConvertBatteryVoltageToPercentage(float voltage)
{
    float minVoltage = 3.3;                     // 最小电压值
    float maxVoltage = 4.15;                    // 最大电压值
    voltage = ((int)(voltage * 100.0)) / 100.0; // 4.066666 -> 406.6666  406 / 100 = 4.06
    if (voltage > maxVoltage)
    {
        return 100.00; // 如果电压大于最大值，直接返回100
    }
    else if (voltage < minVoltage)
    {
        return 0; // 如果电压小于最小值，直接返回0（这里根据你的需求，也可以处理为错误或异常）
    }
    else
    {
        // 线性映射到0-100
        float range = maxVoltage - minVoltage;
        return ((voltage - minVoltage) / range) * 100.0;
    }
}

static void batteryTimerHandler(void)
{
    float rawVoltage = CalculateBatteryVoltage(AdcValue[0]);
    batteryVoltage = filterVoltage_ema(rawVoltage);
    // 如果小于电压阈值则设置触发电量低报警
    if (batteryVoltage < BATTERY_VOLTAGE)
        xEventGroupSetBits(status_event_group, BATTERY_LOW_EVENT);
    else
        xEventGroupClearBits(status_event_group, BATTERY_LOW_EVENT);

    ic_temp = (float)(AdcValue[1] & 0xfff) * 3.3 / 4096;
    ic_temp = (1.43 - ic_temp) / 0.0043 + 25;

    // 温度过高报警
    if (ic_temp >= IC_HIGH_TEMP_PARM)
        xEventGroupSetBits(status_event_group, IC_HIGH_TEMP_EVENT);
    else
        xEventGroupClearBits(status_event_group, IC_HIGH_TEMP_EVENT);
    // 转换为百分比
    batteryPercent = ConvertBatteryVoltageToPercentage(batteryVoltage);
}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
    if (hadc->Instance == ADC1)
    {
        xEventGroupSetBitsFromISR(status_event_group, ADC_READY_EVENT, NULL);
    }
}

/**
 * @brief 电池任务处理函数
 * 该函数用于处理电池电量相关的任务，包括ADC检测、电量计算和显示更新
 */
void battery_task(void *arg)
{
    battery_init();
    xTaskCreate(buzzer_task, "buzzer_task", 128, NULL, osPriorityNormal, NULL);
    EventBits_t event_bits;
    while (1)
    {
        event_bits = xEventGroupWaitBits(status_event_group, ADC_READY_EVENT, pdTRUE, pdTRUE, 0);
        if (event_bits & ADC_READY_EVENT)
            batteryTimerHandler();
        vTaskDelay(800);
    }
}
float getIcTemp(void)
{
    return ic_temp;
}

float getBatteryVoltage(void)
{
    return batteryVoltage;
}

float getBatteryPercent(void)
{
    return (float)stablePercent((int)(batteryPercent + 0.5f));
}
